﻿using System.Runtime.CompilerServices;
using KinonekoSoftware.CodariaDB.Documents.Theories;
using KinonekoSoftware.CodariaDB.Documents.Theories.Elements;
using KinonekoSoftware.CodariaDB.Documents.Theories.Mineral;
using KinonekoSoftware.CodariaDB.Documents.Theories.Rarities;
using KinonekoSoftware.CodariaDB.Documents.Theories.Vocabulary;
using KinonekoSoftware.CodariaDB.Runtimes.Initializers;

namespace KinonekoSoftware.Studio
{
    public static partial class Platform
    {

        /*
         * GetEngines 方法用于快捷的获取数据引擎，而不是手动的赋值
         * 这个过程简化了许多重复的操作
         *
         */
        #region GetEngines

        //
        // Fast Get Engine Help Methods

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T GetEngine<T>() where T : Engine => Ioc.Get<RepositoryRuntime>().GetEngine<T>();

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T GetObject<T>() where T : EmbeddedObject => Ioc.Get<RepositoryRuntime>().Repository.Get<T>();
        
        /// <summary>
        /// 快捷获得
        /// </summary>
        /// <param name="factory"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T GetObject<T>(Factory<T> factory) where T : EmbeddedObject => Ioc.Get<RepositoryRuntime>().Repository.GetOrCreate<T>(factory);

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static IRepository GetRepository() => Ioc.Get<RepositoryRuntime>().Repository;

        public static T GetEngine<T>(out RepositoryRuntime runtime) where T : Engine
        {
            runtime = Ioc.Get<RepositoryRuntime>();
            return runtime.GetEngine<T>();
        }

        public static void GetEngine<TEngine1, TEngine2>(
            out RepositoryRuntime runtime,
            out TEngine1          e1,
            out TEngine2          e2)
            where TEngine1 : Engine
            where TEngine2 : Engine
        {
            runtime = Ioc.Get<RepositoryRuntime>();
            e1      = runtime.GetEngine<TEngine1>();
            e2      = runtime.GetEngine<TEngine2>();
        }

        public static void GetEngine<TEngine1, TEngine2, TEngine3>(
            out RepositoryRuntime runtime,
            out TEngine1          e1,
            out TEngine2          e2,
            out TEngine3          e3)
            where TEngine1 : Engine
            where TEngine2 : Engine
            where TEngine3 : Engine
        {
            runtime = Ioc.Get<RepositoryRuntime>();
            e1      = runtime.GetEngine<TEngine1>();
            e2      = runtime.GetEngine<TEngine2>();
            e3      = runtime.GetEngine<TEngine3>();
        }

        public static void GetEngine<TEngine1, TEngine2, TEngine3, TEngine4>(
            out RepositoryRuntime runtime,
            out TEngine1          e1,
            out TEngine2          e2,
            out TEngine3          e3,
            out TEngine4          e4)
            where TEngine1 : Engine
            where TEngine2 : Engine
            where TEngine3 : Engine
            where TEngine4 : Engine
        {
            runtime = Ioc.Get<RepositoryRuntime>();
            e1      = runtime.GetEngine<TEngine1>();
            e2      = runtime.GetEngine<TEngine2>();
            e3      = runtime.GetEngine<TEngine3>();
            e4      = runtime.GetEngine<TEngine4>();
        }


        public static void GetEngine<TEngine1, TEngine2, TEngine3, TEngine4, TEngine5>(
            out RepositoryRuntime runtime,
            out TEngine1          e1,
            out TEngine2          e2,
            out TEngine3          e3,
            out TEngine4          e4,
            out TEngine5          e5)
            where TEngine1 : Engine
            where TEngine2 : Engine
            where TEngine3 : Engine
            where TEngine4 : Engine
            where TEngine5 : Engine
        {
            runtime = Ioc.Get<RepositoryRuntime>();
            e1      = runtime.GetEngine<TEngine1>();
            e2      = runtime.GetEngine<TEngine2>();
            e3      = runtime.GetEngine<TEngine3>();
            e4      = runtime.GetEngine<TEngine4>();
            e5      = runtime.GetEngine<TEngine5>();
        }
        
        
        public static void GetEngine<TEngine1, TEngine2, TEngine3, TEngine4, TEngine5, TEngine6>(
            out RepositoryRuntime runtime,
            out TEngine1          e1,
            out TEngine2          e2,
            out TEngine3          e3,
            out TEngine4          e4,
            out TEngine5          e5,
            out TEngine6          e6)
            where TEngine1 : Engine
            where TEngine2 : Engine
            where TEngine3 : Engine
            where TEngine4 : Engine
            where TEngine5 : Engine
            where TEngine6 : Engine
        {
            runtime = Ioc.Get<RepositoryRuntime>();
            e1      = runtime.GetEngine<TEngine1>();
            e2      = runtime.GetEngine<TEngine2>();
            e3      = runtime.GetEngine<TEngine3>();
            e4      = runtime.GetEngine<TEngine4>();
            e5      = runtime.GetEngine<TEngine5>();
            e6      = runtime.GetEngine<TEngine6>();
        }
        
        
        public static void GetEngine<TEngine1, TEngine2, TEngine3, TEngine4, TEngine5, TEngine6, TEngine7>(
            out RepositoryRuntime runtime,
            out TEngine1          e1,
            out TEngine2          e2,
            out TEngine3          e3,
            out TEngine4          e4,
            out TEngine5          e5,
            out TEngine6          e6,
            out TEngine7          e7)
            where TEngine1 : Engine
            where TEngine2 : Engine
            where TEngine3 : Engine
            where TEngine4 : Engine
            where TEngine5 : Engine
            where TEngine6 : Engine
            where TEngine7 : Engine
        {
            runtime = Ioc.Get<RepositoryRuntime>();
            e1      = runtime.GetEngine<TEngine1>();
            e2      = runtime.GetEngine<TEngine2>();
            e3      = runtime.GetEngine<TEngine3>();
            e4      = runtime.GetEngine<TEngine4>();
            e5      = runtime.GetEngine<TEngine5>();
            e6      = runtime.GetEngine<TEngine6>();
            e7      = runtime.GetEngine<TEngine7>();
        }

        public static void GetEngine<TEngine1, TEngine2, TEngine3, TEngine4, TEngine5, TEngine6, TEngine7, TEngine8>(
            out RepositoryRuntime runtime,
            out TEngine1          e1,
            out TEngine2          e2,
            out TEngine3          e3,
            out TEngine4          e4,
            out TEngine5          e5,
            out TEngine6          e6,
            out TEngine7          e7,
            out TEngine8          e8)
            where TEngine1 : Engine
            where TEngine2 : Engine
            where TEngine3 : Engine
            where TEngine4 : Engine
            where TEngine5 : Engine
            where TEngine6 : Engine
            where TEngine7 : Engine
            where TEngine8 : Engine
        {
            runtime = Ioc.Get<RepositoryRuntime>();
            e1      = runtime.GetEngine<TEngine1>();
            e2      = runtime.GetEngine<TEngine2>();
            e3      = runtime.GetEngine<TEngine3>();
            e4      = runtime.GetEngine<TEngine4>();
            e5      = runtime.GetEngine<TEngine5>();
            e6      = runtime.GetEngine<TEngine6>();
            e7      = runtime.GetEngine<TEngine7>();
            e8      = runtime.GetEngine<TEngine8>();
        }


        public static void GetEngine<TEngine1, TEngine2, TEngine3, TEngine4, TEngine5, TEngine6, TEngine7, TEngine8, TEngine9, TEngine10, TEngine11>(
            out RepositoryRuntime runtime,
            out TEngine1          e1,
            out TEngine2          e2,
            out TEngine3          e3,
            out TEngine4          e4,
            out TEngine5          e5,
            out TEngine6          e6,
            out TEngine7          e7,
            out TEngine8          e8,
            out TEngine9          e9,
            out TEngine10         e10,
            out TEngine11         e11)
            where TEngine1 : Engine
            where TEngine2 : Engine
            where TEngine3 : Engine
            where TEngine4 : Engine
            where TEngine5 : Engine
            where TEngine6 : Engine
            where TEngine7 : Engine
            where TEngine8 : Engine
            where TEngine9 : Engine
            where TEngine10 : Engine
            where TEngine11 : Engine
        {
            runtime = Ioc.Get<RepositoryRuntime>();
            e1      = runtime.GetEngine<TEngine1>();
            e2      = runtime.GetEngine<TEngine2>();
            e3      = runtime.GetEngine<TEngine3>();
            e4      = runtime.GetEngine<TEngine4>();
            e5      = runtime.GetEngine<TEngine5>();
            e6      = runtime.GetEngine<TEngine6>();
            e7      = runtime.GetEngine<TEngine7>();
            e8      = runtime.GetEngine<TEngine8>();
            e9      = runtime.GetEngine<TEngine9>();
            e10     = runtime.GetEngine<TEngine10>();
            e11     = runtime.GetEngine<TEngine11>();
        }

        #endregion

        public static void Start()
        {
            RepositoryHashCode = ID.GetShortID();
        }

        public static void Close()
        {
            RepositoryHashCode = ID.GetShortID();
            
            //
            // 清空图片缓存
            Cache.Clear();
            ThumbnailCache.Clear();
            
            //
            // 清空关键字缓存。
            Keywords?.Clear();
        }
    }
}